import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import yaml from 'yaml';
import common from '../../../lib/common/common.js';
import { createLogger } from '../modules/Logger.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const CONFIG_PATH = path.resolve(__dirname, "../config/gonggao.yaml");

// 确保配置文件存在
if (!fs.existsSync(path.dirname(CONFIG_PATH))) {
    fs.mkdirSync(path.dirname(CONFIG_PATH), { recursive: true });
}
if (!fs.existsSync(CONFIG_PATH)) {
    const defaultConfig = {
        whiteListBots: [],
        blackListGroups: []
    };
    fs.writeFileSync(CONFIG_PATH, yaml.stringify(defaultConfig));
}

export class AnnouncementPlugin extends plugin {
    constructor() {
        super({
            name: '公告插件',
            dsc: '发送公告到指定机器人的群聊，支持取消群聊公告推送，支持指定机器人推送公告',
            event: 'message',
            priority: 500,
            rule: [
                { reg: "^#公告", fnc: 'announce', permission: 'master' },
                { reg: "^#指定公告\\d+", fnc: 'announceToSpecificBot', permission: 'master' },
                { reg: "^#取消皮皮推送$", fnc: 'cancelPush', permission: 'all' }
            ]
        });
        // 创建日志实例
        this.logger = createLogger(this.name);
    }

    async announce(e) {
        const message = e.msg.slice(3).trim();
        if (!message) {
            await e.reply('请提供要发送的公告消息。');
            this.logger.error('用户未提供公告消息，操作终止');
            return;
        }

        try {
            const configYaml = await fs.promises.readFile(CONFIG_PATH, 'utf-8');
            const config = yaml.parse(configYaml);
            const whiteListBots = config.whiteListBots;
            const blackListGroups = config.blackListGroups;

            this.logger.info(`读取到白名单机器人账号: ${whiteListBots}`);
            this.logger.info(`读取到黑名单群聊: ${blackListGroups}`);

            if (whiteListBots.length === 0) {
                await e.reply('无可用皮皮，无法发送公告哦~');
                this.logger.error('白名单机器人账号为空，无法发送公告');
                return;
            }

            // 反馈开始向哪些机器人账号推送公告，使用换行符分隔
            const botIdsStr = whiteListBots.join('\n');
            await e.reply(`已开始向以下bot账号的所有群聊推送公告：\n${botIdsStr}`);

            let allGroups = [];
            for (const botId of whiteListBots) {
                if (Bot[botId]) {
                    this.logger.info(`找到机器人实例: ${botId}`);
                    allGroups = allGroups.concat(Array.from(Bot[botId].gl.values()));
                } else {
                    this.logger.error(`未找到机器人实例: ${botId}`);
                }
            }

            const groupIds = allGroups.map(group => group.group_id).filter(groupId => !blackListGroups.includes(groupId));
            this.logger.info(`最终要发送公告的群聊 ID: ${groupIds}`);

            const result = await sendMessage(whiteListBots, groupIds, message, e, this.logger);

            await e.reply(`公告已发送，共尝试发送到 ${result.totalGroups} 个群聊，成功 ${result.success} 个，失败 ${result.fail} 个。`);
            this.logger.info(`公告发送完成，尝试 ${result.totalGroups} 个群聊，成功 ${result.success} 个，失败 ${result.fail} 个`);
        } catch (error) {
            this.logger.error(`执行公告发送时出现错误: ${error.message}`);
        }
    }

    async announceToSpecificBot(e) {
        // 修改匹配正则表达式，适应 #指定公告123456 消息 格式
        const match = e.msg.match(/^#指定公告(\d+) (.*)/);
        if (!match) {
            await e.reply('指令格式错误，请使用 #指定公告机器人账号 消息 格式。');
            this.logger.error('用户输入的指定公告指令格式错误');
            return;
        }

        const specificBotId = match[1];
        const message = match[2].trim();

        if (!message) {
            await e.reply('请提供要发送的公告消息。');
            this.logger.error('用户未提供指定公告的消息，操作终止');
            return;
        }

        try {
            const configYaml = await fs.promises.readFile(CONFIG_PATH, 'utf-8');
            const config = yaml.parse(configYaml);
            const blackListGroups = config.blackListGroups;

            if (!Bot[specificBotId]) {
                await e.reply(`未找到机器人实例: ${specificBotId}`);
                this.logger.error(`未找到机器人实例: ${specificBotId}`);
                return;
            }

            await e.reply(`已开始向bot账号：${specificBotId} 的所有群聊，推送公告`);

            const allGroups = Array.from(Bot[specificBotId].gl.values());
            const groupIds = allGroups.map(group => group.group_id).filter(groupId => !blackListGroups.includes(groupId));
            this.logger.info(`最终要向机器人 ${specificBotId} 发送公告的群聊 ID: ${groupIds}`);

            const result = await sendMessage([specificBotId], groupIds, message, e, this.logger);

            await e.reply(`公告已发送，共尝试向机器人 ${specificBotId} 的 ${result.totalGroups} 个群聊发送，成功 ${result.success} 个，失败 ${result.fail} 个。`);
            this.logger.info(`向机器人 ${specificBotId} 公告发送完成，尝试 ${result.totalGroups} 个群聊，成功 ${result.success} 个，失败 ${result.fail} 个`);
        } catch (error) {
            this.logger.error(`执行指定公告发送时出现错误: ${error.message}`);
        }
    }

    async cancelPush(e) {
        const configYaml = await fs.promises.readFile(CONFIG_PATH, 'utf-8');
        const config = yaml.parse(configYaml);
        const blackListGroups = config.blackListGroups;

        if (!blackListGroups.includes(e.group_id)) {
            blackListGroups.push(e.group_id);
            config.blackListGroups = blackListGroups;
            fs.writeFileSync(CONFIG_PATH, yaml.stringify(config));
            await e.reply('已将本群添加到公告推送黑名单中。');
            this.logger.info(`群聊 ${e.group_id} 已添加到黑名单`);
        } else {
            await e.reply('本群已在公告推送黑名单中。');
            this.logger.info(`群聊 ${e.group_id} 已在黑名单中`);
        }
    }
}

async function sendMessage(whiteListBots, groupIds, message, e, logger) {
    logger.info('开始推送公告消息');
    let success = 0;
    let fail = 0;
    const totalGroups = groupIds.length;

    for (const botId of whiteListBots) {
        if (!Bot[botId]) {
            logger.error(`机器人实例 ${botId} 不存在，跳过`);
            continue;
        }
        const botGroups = groupIds.filter(groupId => {
            const group = Bot[botId].gl.get(groupId);
            return group;
        });

        for (const groupId of botGroups) {
            const randomDelay = Math.floor(Math.random() * (2000 - 1000 + 1)) + 1000;
            await common.sleep(randomDelay);

            try {
                await Bot[botId].pickGroup(groupId).sendMsg(message);
                success++;
                logger.info(`群 ${groupId} 消息发送成功`);
            } catch (err) {
                if (err.code === 110) {
                    logger.info(`群 ${groupId} 已被移出，跳过该群`);
                } else {
                    fail++;
                    logger.error(`群 ${groupId} 消息发送失败，错误码: ${err.code}，错误信息: ${err.message}`);
                }
            }
        }
    }

    return { success, fail, totalGroups };
}